package com.linkhub.oms.admin.modules.order.domain.vo;

import cn.hutool.core.collection.CollUtil;
import com.linkhub.oms.common.util.QtStreamUtil;
import com.linkhub.oms.common.util.json.QtFastjsonUtil;
import com.linkhub.oms.data.sync.api.yunexpress.domain.response.CreateOrderResponse;
import com.linkhub.oms.data.sync.api.yunexpress.domain.response.PrintOrderResponse;
import com.linkhub.oms.entity.OrderEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Jaycle
 * @version 1.0.0
 * @Description EmployeeOrderPrintResultVO.java
 * @createTime 2024/07/06 14:41
 */
@Data
@ApiModel("订单预报结果对象")
public class EmployeeOrderPrintResultVO implements Serializable{

    @ApiModelProperty("成功数量")
    private int successTotal;

    @ApiModelProperty("失败数量，数量 > 0 才有失败原因")
    private int failTotal;

    @ApiModelProperty("失败原因")
    private String failReason;

    public static EmployeeOrderPrintResultVO createResult( List<OrderEntity> pendingPrintOrders, Map<Boolean, List<PrintOrderResponse.DefinePrintResult>> partitionDefinePrintResults ) {
        EmployeeOrderPrintResultVO vo = new EmployeeOrderPrintResultVO();
        StringBuilder failReason = new StringBuilder();

        // 获取 partitionDefinePrintResults 中所有的 CustomerOrderNumber
        Set<String> partitionedCustomerOrderNumbers = partitionDefinePrintResults.values().stream()
                .flatMap(List::stream)
                .map(PrintOrderResponse.DefinePrintResult::getCustomerOrderNumber)
                .collect(Collectors.toSet());

        // 过滤 pendingForecastOrders，除去 partitionDefinePrintResults 中的 CustomerOrderNumber
        List<String> remainingOrderNumbers = pendingPrintOrders.stream()
                .filter(order -> !partitionedCustomerOrderNumbers.contains(order.getWayBillNumber()))
                .map(OrderEntity::getOrderNumber)
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(remainingOrderNumbers)) {
            failReason.append(String.format("The order is not ready to print, orderNumbers: [%s]%n",
                    QtFastjsonUtil.toJSONString(remainingOrderNumbers)));
        }

        List<PrintOrderResponse.DefinePrintResult> failedDefinePrintResults = partitionDefinePrintResults.get(false);
        if (CollUtil.isNotEmpty(failedDefinePrintResults)) {
            // 创建一个 wayBillNumber 到 orderNumber 的映射
            Map<String, String> wayBillNumberToOrderNumberMap = pendingPrintOrders.stream()
                    .collect(Collectors.toMap(OrderEntity::getWayBillNumber, OrderEntity::getOrderNumber));
            failedDefinePrintResults.forEach(definePrintResult -> {
                String orderNumber = wayBillNumberToOrderNumberMap.get(definePrintResult.getCustomerOrderNumber());
                String error = definePrintResult.getOrderNumberMess().getError();
                if (orderNumber != null&& error != null) {
                    failReason.append(String.format("The orderNumber [%s] print failed, reason: [%s]%n",
                            orderNumber, error));
                }
            });
        }

        int total = CollUtil.size(pendingPrintOrders);
        int failTotal = CollUtil.size(remainingOrderNumbers) + CollUtil.size(failedDefinePrintResults);
        vo.setFailTotal(failTotal);

        if (failTotal > 0) {
            vo.setFailReason(failReason.toString());
        }

        vo.setSuccessTotal(total - failTotal);

        return vo;
    }
}
